<template>
    <el-dialog 
        class="qs-dialog"
        :visible.sync="visible" 
        :title="title"
        :before-close="handleClose"
        :close-on-click-modal="false"
        :modal="false">
        <el-form :model="formData" ref="formRef" :rules="rules" label-width="136px">
            <el-form-item prop="title" label="问卷名称：">
                <el-input v-model="formData.title" maxLength="60" placeholder="请输入名称" />
            </el-form-item>
            <el-form-item prop="description" label="问卷说明：">
                <el-input 
                    type="textarea" 
                    :rows="6" 
                    placeholder="请输入内容" 
                    v-model="formData.description" 
                    maxlength="600" 
                    show-word-limit />
            </el-form-item>
            <el-form-item prop="selectTime" label="有效时间：">
                <el-date-picker
                    v-model="formData.selectTime"
                    type="datetimerange"
                    range-separator="至"
                    start-placeholder="开始时间" 
                    end-placeholder="结束时间"
                    value-format="timestamp"
                    format="yyyy-MM-dd HH:mm:ss"
                    :default-time="['00:00:00', '23:59:59']"
                    :picker-options="pickerOptions">
                </el-date-picker>
            </el-form-item>
            <el-form-item prop="limit_type" label="答题限制：">
                限制一个用户
                <el-select v-model="formData.limit_type" style="width: 110px;margin: 0 6px;">
                    <el-option 
                        v-for="option of limitType" :value="option.value" :label="option.name" :key="option.value">
                    </el-option>
                </el-select>
                答题1次
            </el-form-item>
            <el-form-item label="新增题目：" prop="questions">
                <el-button 
                    type="primary" v-for="item of actionType" :label="item.id" 
                    :key="item.id" @click="handleAdd(item.id)">
                    {{ item.name }}
                </el-button>
            </el-form-item>
            <el-form-item label="快速题型：">
                <el-button 
                    type="primary" v-for="item of questionType" :label="item.id" 
                    :key="item.id" @click="handleFastAdd(item)">
                    {{ item.name }}
                </el-button>
            </el-form-item>
            <div v-if="formData.questions.length > 0">
                <el-form-item label="题目列表：" class="form-item__questions" prop="questions">
                    <div class="questions-wrapper">
                        <div 
                            v-for="(item, index) of questionsList" :key="`question_${index}`"
                            :class="{'questions-item': true, 'questions-item__shrink': item.is_shrink}">
                            <el-row class="questions-item__header">
                                <el-col :span="12" @click.native="handleShrink(index)">
                                    题目{{ index + 1 }} {{ actionTypeJson[item.type] ? '(' + actionTypeJson[item.type].name + ')' : '' }}
                                    <i class="el-icon-arrow-down"></i>
                                </el-col>
                                <el-col :span="12" class="item__button-group">
                                    <el-select 
                                        v-model="formData.questions[index].multi_rows" v-if="item.type == 3 && +item.multi_rows >= 0" size="mini">
                                        <el-option 
                                            v-for="option of rowsType" :value="option.value" :label="option.name" :key="option.value">
                                        </el-option>
                                    </el-select>
                                    <el-checkbox 
                                        v-if="+item.type == 1"
                                        class="item__is-jump" 
                                        v-model="formData.questions[index].options_jump" >
                                        选项跳转
                                    </el-checkbox>
                                    <el-button 
                                        type="primary" icon="el-icon-top" size="mini" circle title="上移" 
                                        @click.stop="handleSort('up', null, index)">
                                    </el-button>
                                    <el-button 
                                        type="primary" icon="el-icon-bottom" size="mini" circle title="下移"
                                        @click.stop="handleSort('down', null, index)">
                                    </el-button>
                                    <el-button 
                                        type="danger" icon="el-icon-delete" size="mini" circle title="删除"
                                        @click.stop="handleDel(index)">
                                    </el-button>
                                </el-col>
                            </el-row>
                            <div class="questions-item__content">
                                <div class="questions-item__content-title">
                                    <el-form-item
                                        :prop="`questions.${index}.title`" label="标题：" 
                                        label-width="72px" :rules="rules.question_title">
                                        <el-input v-model="formData.questions[index].title" maxLength="60" />
                                        <el-checkbox v-model="formData.questions[index].is_required">必答题</el-checkbox>
                                    </el-form-item>
                                </div>
                                <div class="questions-item__content-option">
                                    <div v-for="(item2, index2) of item.options" :key="`option_${index2}`">
                                        <div class="option-item">
                                            <div :class="{'option-item_input': true, 'option_is-jump': item.options_jump}">
                                                <el-form-item 
                                                    v-if="item.type <= 2"
                                                    :prop="`questions.${index}.options.${index2}.title`" 
                                                    :label="`选项${ index2 + 1 }：`" 
                                                    label-width="72px" 
                                                    :rules="rules.option_title">
                                                    <!-- <el-input v-model="formData.questions[index].options[index2].title" maxLength="60" /> -->
                                                    <el-input v-model="item2.title" maxLength="60" />
                                                </el-form-item>
                                                <el-form-item 
                                                    v-else
                                                    :prop="`questions.${index}.options.${index2}.title`" 
                                                    :label="`选项：`" 
                                                    label-width="72px"
                                                    class="is-required el-form-item-rate">
                                                    <template v-if="item2.type === 'area'">
                                                        <area-select ref="areaRef" :deep="3" class="area-select-wrapper" show-options></area-select>
                                                    </template>
                                                    <template v-else-if="item2.type === 'date'">
                                                        <el-date-picker type="date" placeholder="选择日期"></el-date-picker>
                                                    </template>
                                                    <template v-else-if="item2.type === 'rate'">
                                                        <div class="el-rate">
                                                            <span class="el-rate__item" v-for="text of item2.texts">{{ text }}</span>
                                                        </div>
                                                        <el-rate />
                                                    </template>
                                                </el-form-item>
                                                <el-form-item 
                                                    :prop="`questions.${index}.options.${index2}.next`" 
                                                    :rules="rules.option_next" 
                                                    class="item__content-option-jump"
                                                    v-if="item.options_jump">
                                                    <el-input 
                                                        placeholder="" 
                                                        maxLength="3"
                                                        v-model="item2.next" 
                                                        @input="val => handleInput(val, item2, 'next')"
                                                        @blur="() => handleBlur(index, item2, index2, 'next')">
                                                        <span slot="prepend">跳</span>
                                                        <span slot="append">题</span>
                                                    </el-input>
                                                </el-form-item>
                                                <el-checkbox v-if="item.type <= 2" v-model="item2.is_write" >
                                                    允许填空
                                                </el-checkbox>
                                            </div>
                                            <div class="option__button-group button-icon-color" v-if="item.type <= 2">
                                                <el-button 
                                                    icon="el-icon-top" size="mini" circle title="上移" 
                                                    @click="handleSort('up', item.options, index2)">
                                                </el-button>
                                                <el-button 
                                                    icon="el-icon-bottom" size="mini" circle title="下移"
                                                    @click="handleSort('down', item.options, index2)">
                                                </el-button>
                                                <el-button 
                                                    icon="el-icon-delete" size="mini" circle title="删除"
                                                    @click="handleDel(index2, item.options)">
                                                </el-button>
                                            </div>
                                        </div>
                                    </div>
                                    <div v-if="+item.type <= 2">
                                        <el-form-item 
                                            :label="`选项${ item.options ? item.options.length + 1 : 1 }：`" 
                                            :prop="`questions.${index}.options`"
                                            :rules="rules.options"
                                            label-width="72px" >
                                            <el-input disabled maxLength="60" />
                                            <div class="option__button-group">
                                                <el-button 
                                                    type="primary" icon="el-icon-plus" size="mini" circle title="新增" 
                                                    @click="handleAdd(item.type, item.options, index)">
                                                </el-button>
                                            </div>
                                        </el-form-item>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </el-form-item>
            </div>
            <el-form-item>
                <el-button type="primary" size="small" @click="handleSubmit">确 定</el-button>
                <el-button size="small" @click="handleCancel">取 消</el-button>
            </el-form-item>
        </el-form>
    </el-dialog>
</template>
<script>
import { actionType, rowsType, questionType, limitType } from './action_types.js'
import { compare, filterNumber, dateFormatter } from '@/common/js/util.js'
import AreaSelect from '@/components/home/area.vue'
export default {
    props: {
        visible: {
            type: Boolean,
            default: false
        },
        data: {
            type: Object,
            default: () => ({})
        },
        action: String
    },
    components: { AreaSelect },
    data() {
        const validator = (rule, value, callback) => {
            // const minutes1 = (new Date(value[0])).getMinutes()
            // const minutes2 = (new Date(value[1])).getMinutes()
            // if (value[0] < +new Date(dateFormatter("YYYY-MM-DD HH:mm"))) { // 针对分钟的校验
            if (value[0] < +new Date()) {
                callback(new Error('起始时间必须 ≥ 当前时间'))
            // } else if (minutes1 != 0 && minutes1 != 30) {
            //     callback(new Error('开始时间分钟必须是整点00 或 半点30'))
            // } else if (minutes2 != 0 && minutes2 != 30) {
            //     callback(new Error('结束时间分钟必须是整点00 或 半点30'))
            } else {
                callback()
            }
        }
        return {
            title: '新增问卷',
            formData: {
                questionnaire_id: '',  // 问卷id
                title: '',             // 问卷名称
                description: '',       // 问卷说明
                selectTime: [],        // 有效时间范围
                limit_type: '1',       // 问卷答题限制
                questions: []          // 问卷题目集合
            },
            pickerOptions: {
                disabledDate: time => {
                    return time.getTime() + 8.64e7 < +new Date()
                }
            },
            rules: {
                title: [{ required: true, message: '请输入问卷名称', trigger: ['blur', 'change'] }],
                description: [{ required: true, message: '请输入问卷说明', trigger: ['blur', 'change'] }],
                selectTime: [
                    { required: true, message: '请选择有效时间', trigger: ['blur', 'change'] },
                    { validator, trigger: ['blur', 'change'] }
                ],
                limit_type: [{ required: true, message: '请选择答题限制类型', trigger: 'change' }],
                questions: [{ required: true, message: '请新增问卷题目', trigger: ['blur', 'change'] }],
                question_title: [{ required: true, message: '请输入标题名称', trigger: ['blur', 'change'] }],
                options: [{ required: true, message: '请添加题目选项', trigger: ['blur', 'change'] }],
                option_title: [{ required: true, message: '请输入选项名称', trigger: ['blur', 'change'] }],
                option_next: [{ required: true, message: '请输入题目序号', trigger: ['blur', 'change'] }]
            },
            limitType: limitType(),    // 答题限制可续
            actionType: actionType(),  // 问卷类型
            actionTypeJson: actionType(true),  // 问卷类型 - 对象形式
            questionType: questionType(),  // 快速题型
            rowsType: rowsType()
        }
    },
    watch: {
        visible: {
            immediate: true,
            handler(val) {
                if (val) {
                    const { questionnaire_id } = this.data
                    if (questionnaire_id) {
                        this.title = this.action === 'edit' ? "编辑问卷" : '复制问卷'
                        this.getData()
                    } else {
                        this.title = "新增问卷"
                    }
                    this.formData.questionnaire_id = questionnaire_id
                }
            }
        }
    },
    computed: {
        questionsList() {
            return this.handleSortInit(this.formData.questions || [])
        }
    },
    methods: {
        handleAdd(type, item = null, option_index = null) {
            const isOption = item ? true : false // 是否为选项
            item = item ?? this.formData.questions
            const index = item.length
            let obj = { title: '', sort: +item[index - 1]?.sort + 1 || 1 }
            if (!isOption) {
                obj = { question_id: 0, type, ...obj, is_required: false, options: [], is_shrink: false }
                if (type == 3) obj.multi_rows = 0
                this.$refs.formRef.clearValidate('questions') // 移除添加题目校验
            } else {
                obj.next = ''
                obj.is_write = false
                this.$refs.formRef.clearValidate(`questions.${option_index}.options`) // 移除添加选项校验
            }
            item.push(obj)
        },
        handleFastAdd(item) {
            const question = { ...item.question }
            question.sort = this.formData.questions.length + 1
            this.formData.questions.push(question)
            this.$refs.formRef.clearValidate('questions')
        },
        handleDel(index, item = null) {
            const content = item ? '选项' : '题目'
            this.$alert(`确定删除${content}${index + 1}？`,"温馨提示", {
                type: 'warning',
                showCancelButton: true
            }).then(() => {
                const _item = item ?? this.formData.questions
                _item.splice(index, 1)
                _item.forEach((val, i) => {
                    val.sort = i + 1
                    if (!item) {
                        const error = []
                        val.type == 1 && val.options?.forEach((val2, i2) => {
                            if (+val2.next == index + 1) {
                                if (!error[i]) {
                                    error[i] = [i2 + 1]
                                } else {
                                    error[i].push(i2 + 1)
                                }
                                val2.next = ''
                            } else if (+val2.next > index + 1) {
                                val2.next = +val2.next - 1
                            }
                        })
                        this.handleError(error, 1)
                    }
                })
            }).catch(() => {})
        },
        handleError(error = [], step = 1) {
            if (error.length > 0) {
                const msg = []
                error.forEach((val, index) => {
                    msg.push(`(题目${index + step}, 选项[${val.join(", ")}])`)
                    val.forEach((_val, _index) => {
                        this.$nextTick(() => {
                            this.$refs.formRef.validateField([`questions.${index + step - 1}.options.${_index}.next`]) // 校验
                        })
                    })
                })
                this.$alert(`请重新设置 ${msg.join("，")} 的跳转`, '温馨提示')
            }
        },
        handleSortInit(data) {
            data.sort(compare("sort", true)) 
            return data.map(child => {
                if (child.options && child.options.length > 0) {
                    this.handleSortInit(child.options)
                }
                return child
            })
        },
        handleSort(action = 'up', _item = null, index) {
            const item = _item ?? this.formData.questions
            const [prev, active, next] = [item[index - 1], item[index], item[index + 1]]
            /**
             * 因题目或选项可能被删除，删除后造成sort不连续，所以我们用下标来更新sort值，保证sort的连续性
             */
            const [prevValue, activeValue, nextValue] = [index, index + 1, index + 2] 
            if (action == 'up' && prev) {
                active.sort = prevValue
                prev.sort = activeValue
                !_item && this.handleOptionNext(item, activeValue, prevValue)
            } else if (action == 'down' && next) {
                active.sort = nextValue
                next.sort = activeValue
                !_item && this.handleOptionNext(item, activeValue, nextValue)
            }
        },
        // 针对题目重新排序后，更改跳题值
        handleOptionNext(obj, value, newValue) {
            const error = []
            obj.forEach((child, index) => {
                if (child.type == 1) { // 只针对单选题
                    child.options?.forEach((_child, _index) => {
                        if (child.options_jump && _child.next) {
                            if (_child.next == value) _child.next = newValue
                            else if (_child.next == newValue) _child.next = value
                            /**
                             * 判断选项所跳转的题目序号是否小于选项所在题目本身的序号，防止向上跳转
                             */
                            if (_child.next <= index + 1) {
                                if (!error[index]) {
                                    error[index] = [_index + 1]
                                } else {
                                    error[index].push(_index + 1)
                                }
                            } else {
                                return 
                            }
                        }
                        _child.next = ''
                    })
                }
            })
            this.handleError(error, 2)
        },
        handleShrink(index) {
            const { questions } = this.formData
            questions[index].is_shrink = !questions[index].is_shrink
            this.formData.questions = [ ...questions ]
        },
        handleInput(val, obj, key) {
            obj[key] =  filterNumber(val, 0)
        },
        handleBlur(index, obj, index2, key) {
            const val = obj.next
            if (val && (+val <= (index + 1) || !this.questionsList[+val - 1])) {
                obj[key] = ''
                return this.$alert(`请正确设置题目${index + 1}, 选项${index2 + 1}的跳转`, '温馨提示')
            }
        },
        getData() {
            const datas = { params: {questionnaire_id: this.data.questionnaire_id} }
            this.$http.get('/admin/yt_car/index.php?act=questionnaire&op=questionnaireInfo', datas).
            then(res => {
                if (res.code == 1) {
                    this.formData = { ...this.formData, ...res.data }
                    const { start_time, end_time } = this.formData
                    if (start_time && end_time) {
                        this.formData.selectTime = [ start_time * 1000, end_time * 1000 ]
                    }
                } else {
                    throw res.msg
                }
            }).catch(error => {
                error && this.$message.error(`${error}`)
            })
        },
        handleSubmit() {
            this.$refs.formRef.validate(valid => {
                if (valid) {
                    const { selectTime, ...datas } = this.formData
                    datas.start_time = selectTime[0] / 1000
                    datas.end_time = selectTime[1] / 1000
                    datas.questions = JSON.stringify(datas.questions)
                    if (this.action === 'copy') {
                        datas.questionnaire_id = 0
                    }
                    this.$http.post("/admin/yt_car/index.php?act=questionnaire&op=saveQuestionnaire", datas)
                    .then(res => {
                        if (res.code == 1) {
                            this.$message.success(datas.questionnaire_id ? '编辑成功' : '新增成功')
                            this.handleClose()
                            this.$emit("update")
                        } else {
                            throw res.msg
                        }
                    }).catch(error => {
                        error && this.$message.error(`${error}`)
                    })
                }
            })
        },
        handleClose() {
            this.formData.questions = []
            /**
             * resetFields() 等questions = [] 渲染后执行，以解决，直接执行resetFields()造成
             * `questions.${index}.title` 因获取不到值而提示异常：
             * Error: please transfer a valid prop path to form item!
             */
            this.$nextTick(() => {
                this.$refs.formRef.resetFields()
            })
            this.$emit("update:visible", false)
        },
        handleCancel() {
            this.handleClose()
        }
    },
    mounted() {
    }
}
</script>
<style lang="scss" scoped>
.question-dialog__date-picker {
    .el-time-spinner__wrapper + .el-time-spinner__wrapper {
        .el-time-spinner__item { 
            color: #c0c4cc!important;
            cursor: not-allowed!important;
        }
    }
}
.qs-dialog {
    height: 100%;
    position: absolute;
    background-color: #F5F7FA;
    overflow: hidden;
    /deep/ .el-dialog__body {
        overflow: auto;
        max-height: calc(100% - 55px);
        padding-bottom: 20px;
        &::-webkit-scrollbar { 
            width: 10px;
            height: 10px;
        }
        &::-webkit-scrollbar-thumb {
            cursor: pointer;
            background-color: rgba(144, 147, 153, 0.25);
            background-clip: padding-box;
            border-right: 1px solid transparent;
            border-bottom: 1px solid transparent;
            border-radius: 8px;
        }
        > .el-form {
            min-width: 820px;
            margin: auto;
            overflow: hidden;
        }
    }
    /deep/ .el-dialog {
        width: calc(100% - 32px);
        height: calc(100% - 32px);
        margin: 16px!important;
        box-shadow: none;
        border: 1px solid #DCDFE6;
        .el-form-item__label {
            padding-right: 6px;
        }
    }
    .el-input, .el-textarea, .questions-wrapper {
        max-width: 680px;
        width: 100%;
    }
    /deep/ .el-radio-button__inner {
        padding: 9px 18px 10px;
    }
    .questions-wrapper .questions-item {
        width: 100%;
        box-sizing: border-box;
        border: 1px solid #DCDFE6;
        border-radius: 4px;
        &:not(:last-child) {
            margin-bottom: 10px;
        }
        .questions-item__header {
            background-color: #F5F7FA;
            padding: 3px 15px 4px;
            .el-col:first-child {
                cursor: pointer;
                font-weight: bold;
                font-size: 13px;
                i {
                    transition: all .3s;
                }
            }
            .el-col:last-child {
                text-align: right;
            }
        }
        .item__button-group {
            .el-select /deep/ {
                width: 108px;
                margin-right: 10px;
                .el-input__inner {
                    line-height: 26px;
                    height: 26px;
                    vertical-align: bottom;
                }
            }
        }
        .item__button-group, .option__button-group {
            .el-button--mini.is-circle {
                padding: 2px 2.5px;
            }
        }
        .option__button-group {
            margin-top: -1.5px;
        }
        .item__is-jump {
            margin-right: 12px;
        }
        .button-icon-color button {
            color: #409EFF;
            border-color: #409EFF;
            &:last-child {
                color: #F56C6C;
                border-color: #F56C6C;
            }
        }
        .questions-item__content {
            padding: 16px 15px 0;
            border-top: 1px dotted #DCDFE6;
            transition: all .3s;
        }
        /deep/ .el-checkbox__label {
            padding-left: 8px;
        }
        &.questions-item__shrink {
            .questions-item__header i {
                transform: rotate(-90deg);
            }
            .questions-item__content {
                padding-top: 0;
                height: 0;
                overflow: hidden;
                border-top-width: 0;
            }
        }
        .option-item, .option-item_input {
            display: flex;
            justify-content: space-between;
        }
        
        .el-input, .area-select-wrapper, .el-rate {
            width: 397px;
        }
        .el-form-item /deep/ {
            .el-form-item__label {
                padding-right: 0;
                text-align: left;
            }
            .el-form-item__content {
                display: flex;
                align-items: center;
                .el-input {
                    margin-right: 12px;
                }
            }
        }
        .option_is-jump .el-form-item {
            /deep/ .el-form-item__content {
                .el-input {
                    width: 300px;
                    margin-right: 0;
                }
                .el-input__inner {
                    border-top-right-radius: 0;
                    border-bottom-right-radius: 0;
                }
            }
            &.item__content-option-jump /deep/ {
                width: 97px;
                margin-right: 12px;
                .el-form-item__content {
                    .el-input-group__prepend, 
                    .el-input-group__append {
                        padding: 0 8px;
                    }
                    .el-input-group__prepend {
                        border-top-left-radius: 0;
                        border-bottom-left-radius: 0;
                        border-left-width: 0;
                    }
                    .el-input {
                        .el-input__inner {
                            padding: 0 6px;
                            text-align: center;
                            border-radius: 0px;
                        }
                    }
                }
            }
        }
        .area-select-wrapper /deep/ {
            .el-form {
                display: flex;
                .el-form-item {
                    flex: 1;
                    &:last-child {
                        margin-right: 0;
                    }
                    .el-form-item__content {
                        width: 100%;
                    }
                    .el-select, .el-input {
                        width: 100%;
                    }
                }
            }
        }
        .el-form-item-rate /deep/ {
            .el-form-item__content {
                flex-direction: column;
            }
            .el-rate {
                display: flex;
                height: 18px;
                .el-rate__item {
                    flex: 1;
                    text-align: center;
                    font-size: 14px;
                    line-height: 100%;
                }
                .el-rate__icon {
                    margin-right: 0;
                }
            }
        }
    }
}
</style>